<template>
  <Category :disabled="!isShow"/>

  <div v-show="isShow">
    <el-card
      shadow="always"
      :body-style="{ padding: '20px' }"
      :style="{ marginTop: '30px' }"
    >
      <template #header>
        <el-button
          type="primary"
          size="default"
          @click="addAttr"
          :icon="Plus"
          :disabled="!category3Id"
          >新增属性</el-button
        >
      </template>
      <!-- card body -->
      <el-table border stripe :data="tableData">
        <el-table-column label="序号" type="index" width="80" />
        <el-table-column
          label="属性名称"
          width="150"
          prop="attrName"
        ></el-table-column>
        <el-table-column label="属性值名称列表" prop="attrValueList">
          <template v-slot="{ row }">
            <el-tag
              style="margin: 5px"
              type="danger"
              size="default"
              effect="dark"
              v-for="item in row.attrValueList"
              :key="item.id"
            >
              {{ item.valueName }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template v-slot="{ row }">
            <el-button
              type="warning"
              size="default"
              @click="editAttr(row)"
              :icon="Edit"
            ></el-button>
            <el-popconfirm title="你确定要删除吗?" @confirm="deleteAttr(row)">
              <template #reference>
                <el-button
                  type="danger"
                  size="default"
                  :icon="Delete"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>

  <div v-show="!isShow" :style="{ marginTop: '30px' }">
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <!-- card body -->
      <el-form label-width="80px" :inline="true">
        <el-form-item label="属性名">
          <el-input
            placeholder="请输入属性名"
            v-model="newAttrData.attrName"
          ></el-input>
        </el-form-item>
      </el-form>
      <div style="margin-bottom: 30px">
        <el-button type="primary" @click="addAttrValue" :disabled="!newAttrData.attrName">添加属性值</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
      <el-table border stripe :data="newAttrData.attrValueList">
        <el-table-column type="index" width="50" label="序号" />
        <el-table-column label="属性值名称" prop="valueName">
          <template v-slot="{ row, $index }">
            <el-input
              v-model="row.valueName"
              placeholder="请输入新增的属性值名称"
              size="default"
              ref="inputRef"
              v-if="row.isEdit"
              @blur="getValueName(row, $index)"
              @focus="saveOldValue(row)"
              @keyup.enter="getValueName(row, $index)"
            ></el-input>
            <p
              v-else
              @click="getFocus(row)"
              :style="{ display: 'inline-block', width: '70%' }"
            >
              {{ row.valueName }}
            </p>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ $index }">
            <el-popconfirm
              title="你确定要删除吗?"
              @confirm="deleteAttrValue($index)"
            >
              <template #reference>
                <el-button
                  type="danger"
                  size="default"
                  @click=""
                  icon="ele-Delete"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin-top: 30px">
        <el-button type="primary" @click="upOrEditHandel" :disabled="newAttrData.attrValueList.length === 0">保存</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from "element-plus";

export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import useAttrStore from "@/stores/attr";
import { watch, ref, nextTick } from "vue";
import { storeToRefs } from "pinia";
import {
  getAddOrUpRequest,
  getAttrListRequest,
  getDeleteAttrRequest,
  type getAttrItemType,
  type getAttrListType,
  type getAttrReturnType,
} from "@/api/attr";
import cloneDeep from "lodash/cloneDeep";

const attrStore = useAttrStore();

//解构categoryId
const { category1Id, category2Id, category3Id } = storeToRefs(attrStore);

const tableData = ref<getAttrReturnType>([]);

//控制新增和修改页面的显隐
const isShow = ref(true);
//1.获取属性列表的逻辑

//封装获取列表函数
const getAttrList = async () => {
  const re = await getAttrListRequest(
    category1Id.value as number,
    category2Id.value as number,
    category3Id.value as number
  );
  tableData.value = re;
};
//监听category3Id的变化
watch(
  category3Id,
  async (newValue) => {
    if (!newValue) {
      tableData.value = [] ;
      return
    };
    //调用获取列表函数
    getAttrList();
  },
  { immediate: true }
);
//2.添加平台属性逻辑

//定义一个新增平台属性的一个初始数据,将来新增点击保存的时候,把这个值提交
const newAttrData = ref<getAttrItemType>({
  attrName: "",
  categoryId: category3Id.value as number,
  categoryLevel: 3,
  attrValueList: [],
});
//新增属性逻辑
const addAttr = () => {
  //控制新增和修改页面的显隐
  isShow.value = false;
  //每次新增的时候,清空上一次可能残留的数据(重新给newAttrData赋一个初始值)
  newAttrData.value = {
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: [],
  };
};

//给新增的属性 添加属性值的事件回调函数

const addAttrValue = () => {
  //创建一个属性值的数据
  const newAttrValue = ref<getAttrListType>({
    valueName: "",
    attrId: newAttrData.value.id,
    isEdit: true,
  });
  //把新增的属性值数据  添加到新属性的  属性值列表的数组中
  newAttrData.value.attrValueList.push(newAttrValue.value);
  nextTick(() => {
    inputRef.value?.focus();
  });
};
//取消新增或者修改的功能及视图
const cancel = () => {
  //先切换到属性列表页
  isShow.value = true;
};

//在属性列表中修改某个属性的事件方法
const editAttr = (row: getAttrItemType) => {
  isShow.value = false;
  const newRow = row;
  newRow.attrValueList.forEach((item) => (item.isEdit = false));
  //回填数据,因为视图和初始新增数据的newAttrData进行深度绑定,所以回填的时候,直接把被修改的数据赋值给newAttrData即可
  newAttrData.value = cloneDeep(newRow);
};

//获取焦点回调
const inputRef = ref<HTMLInputElement>();

const getFocus = (row: getAttrListType) => {
  row.isEdit = true;
  nextTick(() => {
    inputRef.value?.focus();
  });
};

//获取焦点的时候把旧值保存下来
let olderAttrValue = "";
const saveOldValue = (row: getAttrListType) => {
  //先把当前的旧值保存起来
  olderAttrValue = row.valueName;
};

//当input失去焦点回调
const getValueName = (row: getAttrListType, index: number) => {
  //把当前的数据中的isEdit变为false
  row.isEdit = false;
  //判断输入是否为空
  if (!row.valueName.trim()) {
    // //如果输入为空,并且旧值也为空,那么说明当前是新增属性值,并且用户没有填,直接删除
    if (!olderAttrValue) {
      newAttrData.value.attrValueList.splice(index, 1);
    } else {
      row.valueName = olderAttrValue;
    }
  }

  //判断用户输入的是否有重复选项,如果有,则恢复

  let isRepeat = newAttrData.value.attrValueList.some((item) => {
    //如果自己比较自己的时候,我们跳过(不挑过的话,永远isRepeat为true)
    if (item === row) {
      return;
    }
    //在判断输入的是否有相同的
    return item.valueName === row.valueName;
  });

  //判断在数据列表中除了row自身以外,还有没有谁的valueName值和row的相等,如果有,则恢复旧值
  if (isRepeat) {
    if (olderAttrValue) {
      row.valueName = olderAttrValue;
    } else {
      newAttrData.value.attrValueList.splice(index, 1);
    }
  }
  //统一在失去焦点事件结束的时候 清空旧值
  olderAttrValue = "";
};

//删除某个属性的值
const deleteAttrValue = (index: number) => {
  newAttrData.value.attrValueList.splice(index, 1);
};

//保存逻辑
const upOrEditHandel = async () => {
  //把请求参数中不需要的isEdit属性删掉，并且删除空串
  newAttrData.value.attrValueList.forEach((item) => {
    delete item.isEdit;
  });

  //如果属性值列表没有属性值，不发送请求
  if (!newAttrData.value.attrValueList.length) {
    ElMessage.warning("属性列表必须有值");
    return;
  }
  try {
    await getAddOrUpRequest(newAttrData.value);
    ElMessage.success("新增或修改成功");
    //新增或修改成功重新调用获取列表函数
    getAttrList();
    isShow.value = true;
  } catch (error) {
    ElMessage.error("保存或修改失败");
  }
};

//删除attr逻辑
const deleteAttr = async (row:getAttrListType) => {
  
  try {
    await getDeleteAttrRequest(row.id as number);
    //删除成功重新调用获取列表函数
    getAttrList();
    ElMessage.success("删除成功");
  } catch (error) {
    ElMessage.error("删除失败");
  }
}
</script>
